home *** CD-ROM | disk | FTP | other *** search
- /*<Header>==============================================================
- *
- * WIZME / "WIZ_IR.C" WIZリンクソフト / ワイヤレスコマンダー操作ブロック
- *
- * [ EIN(tm) project : サンプルプログラム ]
- *
- * COPYRIGHT Nam 1995, All rights reserved.
- *
- * 配付・組込・改変・商利用すべて自由。ただし無保証っす
- *
- *-----------------------------------------------------------------------
- * V1.0L01α 95.08.04/Nam プロトタイプ
- * (サンプルのZR.C,Z.Cを参考にさせて頂きました)
- * V1.0L02α 95.08.08/Nam 右クリック中断
- *</Header>==============================================================*/
- #include <stdio.h>
- #include <ctype.h>
- #include <mos.h> // このサンプルでのみ必要
-
-
- #define LEFT 0
- #define RIGHT 1
-
- #define ERROR (-1)
- #ifndef NOERR
- #define NOERR (0)
- #endif
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
-
- #define ZRCVMAX (512+17+1)
- #define BLOCKMAX (512)
-
- #define ENQ (0x05)
- #define SYN (0x16)
- #define ACK (0x06)
- #define NACK (0x15)
- #define CAN (0x18)
-
- #define RETRY (4)
-
- extern int termSize; // 元データバッファ内データサイズ(bytes)
-
- int irPort; // IR送受信用ポート番号(0/1)
-
- BYTE irBuf[ZRCVMAX]; // IR送受信用バッファ
- BYTE repBuf[ZRCVMAX]; // IR送受信リトライ時再送信用バッファ
-
- BYTE enqDat[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x82, ENQ },
- synDat[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x82, SYN },
- ackDat[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x82, ACK },
- nacDat[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x82, NACK },
- canDat[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x82, CAN };
-
-
- extern int rmcCommand ( int, BYTE );
- extern int rmcSendStop ( int );
- extern int rmcRecieveByte( int, BYTE * );
- extern int rmcRecieveStop( int );
- extern int rmcSendByte ( int, BYTE );
- extern int rmcPutZaurus ( int, BYTE *, int, BYTE *, int, int * );
- extern int rmcGetZaurus ( int, BYTE *, int, int * );
- extern void wait200mic ( void ); // 200マイクロ秒待ち
-
- extern int DM_showMsg();
- extern int DM_dispCount();
-
- extern int WL_recBuf();
- extern int WL_recRBuf();
- extern int WL_mkSendBuf();
-
- int IR_checkBreak()
- {
- int btn, bx, by;
- // 現在のマウスカーソルの位置を読む
- MOS_rdpos( &btn, &bx, &by );
- // 右クリックか?
- if ( (btn & 0x02) != 0 ){
- // 終了処理
- rmcSendStop( irPort );
- DM_showMsg( "※中断したっス", NULL);
- return 1;
- }
- return 0;
- }
-
- int IR_waitBreak( int sec )
- {
- int btn, bx, by, i;
-
- for( i = 0; i < (sec * 1000 * 5); i++ ){ /* タイムアウト迄 */
- /*(=(200μsec * 5 * 1000)*sec秒) */
- // 右クリック中断
- // 現在のマウスカーソルの位置を読む
- MOS_rdpos( &btn, &bx, &by );
- // 右クリックか?
- if ( (btn & 0x02) != 0 ){
- return ERROR;
- }
- wait200mic(); /* (200マイクロ秒待ち) */
- }
- return NOERR;
- }
-
- void IR_dispErrWC( int err )
- {
- switch( err )
- {
- case 1:
- DM_showMsg( "※ワイヤレスコマンダがはずれたっス", NULL);
- break;
- case 2:
- DM_showMsg( "※中断したっス", NULL);
- break;
- default:
- DM_showMsg( "※ワイヤレスコマンダが見あたらないっス","(もし繋がってるなら電池を交換してね)" );
- break;
- }
- }
-
- int IR_checkWC()
- {
- int ret;
- BYTE stt;
-
- irPort = RIGHT;
- ret = rmcCommand ( irPort, 0x33 ); /* バッテリチェック */
- if( ret == 1 ){ /* 右 非接続 */
- irPort = LEFT;
- ret = rmcCommand ( irPort, 0x33 );
- }
- if( ret != 0 ){
- if( rmcSendStop( irPort ) ){
- // IR_dispErrWC( 0 ); // 『ワイヤレスコマンダが見当たりません』表示
- }
- IR_dispErrWC( 0 ); // 『ワイヤレスコマンダが見当たりません』表示
- return ERROR;
- }
- ret = rmcRecieveByte( irPort, &stt );
- if( ret != 0 ){
- if( ret != 1 && rmcRecieveStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- }
- return ERROR;
- }
- // printf( "電池:%s [ROM-Ver=%02X]", (stt & 0x40)?"OK":"NG", (stt & 0x3f) );
- if( rmcSendStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- if ( !(stt & 0x40) ){
- DM_showMsg( "※ワイヤレスコマンダの電池を交換してください", NULL);
- return ERROR;
- }
- return NOERR;
- }
-
-
- int IR_repChk( BYTE *p, int cnt, BYTE ctrl )
- {
- if( cnt == 8 &&
- p[ 0 ] == 0x00 && p[ 1 ] == 0x00 && p[ 2 ] == 0x00 &&
- p[ 3 ] == 0x00 && p[ 4 ] == 0x00 && p[ 5 ] == 0x96 &&
- p[ 6 ] == 0x82 && p[ 7 ] == ctrl ){
- return 0;
- }
- return 1;
- }
-
- int IR_rlastBlock( int blockNo, BYTE *p, int cnt )
- {
- BYTE headr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x81 };
- int i;
- WORD sum;
-
- if( cnt < 15 ){
- // ヘッダ長不足
- return 2;
- }
- for( i = 0; i < sizeof( headr ); i++ ){
- if( p[ i ] != headr[ i ] ){
- // ヘッダ部異常
- return 3;
- }
- }
- if( cnt != 15 + *(WORD *)( p + 13 ) + 2 ){
- // データ長異常
- return 4;
- }
- for( i = sum = 0; i < *(WORD *)( p + 13 ); i++ ){
- sum += *( p + 15 + i );
- }
- if( sum != *(WORD *)( p + 15 + *(WORD *)( p + 13 ) ) ){
- // チェックサム エラー
- return 5;
- }
- if( *(WORD *)( p + 8 ) == 0xffff ){
- // 最終ブロックである
- return 1;
- }
- if( *(WORD *)( p + 8 ) != blockNo ){
- // ブロックNo.エラー
- return 6;
- }
- return 0;
- }
-
- int IR_waitENQ( int irPort )
- {
- int i, rcnt, ret;
-
- for( i = 0; i < 3000; i++ ){
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return 2;
- }
- ret = rmcPutZaurus( irPort, NULL, 0, repBuf, ZRCVMAX, &rcnt );
- if( ret!=0 && ret < 10 ){
- // printf( "\nENQ待ち時" );
- WL_recRBuf( rcnt );
- DM_dispCount( 0 );
- return 1;
- }
- if( !rcnt )
- continue;
- if( !IR_repChk( repBuf, rcnt, ENQ ) )
- return( 0 );
- }
- // printf( "\nENQ待ちタイムアウト" );
- return 1;
- }
-
-
- // 同期受信
- int IR_syncRead( void )
- {
- int ret, ret2, cnt, rcnt, i, j;
-
- DM_showMsg( "◆ オプション受信モード (右クリックで中断)◆", "(Wizから送信して下さい)" );
- DM_dispCount( -1 ); // カウンタクリア
-
- /* コマンド送信 */
- ret = rmcCommand ( irPort, 0x74 ); /* 最初のコマンド */
- if( ret == 1 ){
- /* 非接続 */
- irPort = ( irPort == RIGHT )? LEFT : RIGHT;
- ret = rmcCommand ( irPort, 0x74 );
- }
- if( ret != 0 ){
- goto loop1;
- }
-
- ret = rmcSendByte( irPort, 0x01 ); /* 二番目のコマンド */
- if( ret != 0 ){
- goto loop1;
- }
-
- /* データ受信 */
- for( i = 0; i < BLOCKMAX; i++ ){
- for( j = 0; j < RETRY; j++ ){
- loop3:
- if( (ret=IR_waitENQ( irPort ))!=0 ){
- /* wait ENQ code */
- // printf( "\nENQ受信時" );
- if ( ret==2 ){
- // 右クリック中断
- return ERROR;
- }
- goto loop1;
- }
- /* put SYN & data get*/
- do ret = rmcPutZaurus( irPort, synDat, 8,
- irBuf, ZRCVMAX, &cnt );
- while( ret == -1 );
-
- if( ret!=0 && ret < 10 ){
- /* 13,14はリトライ可能 */
- // printf( "\nSYN送信時" );
- // zdumpData( irBuf, cnt );
- WL_recBuf( cnt );
- DM_dispCount( 0 );
- goto loop1;
- }
-
- if( !IR_repChk( irBuf, cnt, ENQ ) ){
- goto loop3;
- }
- /* data check */
- if( !ret ){
- ret2 = IR_rlastBlock( i+1, irBuf, cnt );
- /* ブロックNo.エラー */
- if( ret2 == 6 && *(WORD *)( irBuf + 8 ) < i + 1 ){
- /* リトライ時に前ブロック再受信 */
- /* 途中 ack */
- do ret = rmcPutZaurus( irPort, ackDat, 8, repBuf,
- ZRCVMAX, &rcnt );
- while( ret == -1 );
-
- if( ret!=0 && ret < 10 ){
- // printf( "\nACK送信時");
- goto loop1;
- }
- continue;
- }
- }
- //※ if( ret || ret2 > 1 )
- if( (ret || ret2 > 1) && ret2!=3 ){
- // printf("retry: %d %d\n", ret, ret2 );
- if( j == RETRY - 1 ){
- /* リトライオーバーCAN */
- do ret = rmcPutZaurus( irPort, canDat, 8, repBuf,
- ZRCVMAX, &rcnt );
- while( ret == -1 );
- // printf( "\n受信リトライエラー" );
- // zdumpData( irBuf, cnt );
- WL_recBuf( cnt );
- DM_dispCount( 0 );
- goto loop1;
- }
- /* データエラー NACK */
- do ret = rmcPutZaurus( irPort, nacDat,
- 8, irBuf, ZRCVMAX, &cnt );
- while( ret == -1 );
- if( ret!=0 && ret < 10 ){
- // printf( "\nNACK送信時" );
- DM_dispCount( 0 );
- goto loop1;
- }
- continue;
- }
-
- // printf( "\nブロック[%d] 受信 (Len=%d)", i + 1, cnt );
- // printf( "[%d] ", i + 1);
- WL_recBuf( cnt );
- DM_dispCount( 0 );
-
- if( ret2 == 0 ){
- /* 非最終ブロック OK */
- /* 途中 ack */
- do ret = rmcPutZaurus( irPort, ackDat,
- 8, repBuf, ZRCVMAX, &rcnt );
- while( ret == -1 );
-
- if( ret!=0 && ret < 10 ){
- // printf( "\nACK送信時" );
- DM_dispCount( 0 );
- goto loop1;
- }
- break;
- } else {
- /* 最終ブロック OK */
- /* 最後 ack */
- do ret = rmcPutZaurus( irPort, ackDat,
- 8, repBuf, ZRCVMAX, &rcnt );
- while( ret == -1 );
-
- if( ret!=0 ){
- // printf( "\nACK送信時" );
- DM_dispCount( 0 );
- goto loop1;
- }
- goto loop7;
- }
- }
- }
- loop7:
- /* 受信処理終了 */
- if( rmcRecieveStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
-
- loop1:
- if( rmcSendStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- return NOERR;
- }
-
- // 同報受信
-
- int IR_onsideRead( void )
- {
- int ret, cnt, i;
-
- DM_showMsg( "◆ 光受信モード ◆", "(Wizの『光送信』をクリックして下さい)" );
- DM_dispCount( -1 ); // カウンタクリア
-
- /* コマンド送信 */
- ret = rmcCommand ( irPort, 0x74 ); /* 最初のコマンド */
- if( ret == 1 ){
- /* 非接続 */
- irPort = ( irPort == RIGHT )? LEFT : RIGHT;
- ret = rmcCommand ( irPort, 0x74 );
- }
- if( ret != 0 ){
- goto loop1;
- }
-
- ret = rmcSendByte( irPort, 0x01 ); /* 二番目のコマンド */
- if( ret != 0 ){
- goto loop1;
- }
-
- /* データ受信 */
- for( i = 0; i < BLOCKMAX; i++ ){
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return ERROR;
- }
- ret = rmcGetZaurus( irPort, irBuf, ZRCVMAX, &cnt);
- if ( ret != 0 || !cnt ){
- // printf(" ret=%d, cnt=%d\n", ret, cnt);
- if( cnt ){
- WL_recBuf( cnt );
- }
- goto loop1;
- }
- switch( IR_rlastBlock(i+1, irBuf, cnt) ){
- case 0:
- // zdumpData( irBuf, cnt );
- // printf( "\nブロック %d 受信", i + 1 );
- WL_recBuf( cnt );
- DM_dispCount( 0 );
- continue;
- case 1:
- // zdumpData( irBuf, cnt );
- // printf( "\nブロック %d 受信", i + 1 );
- WL_recBuf( cnt );
- DM_dispCount( 0 );
- goto inEnd;
- default:
- goto loop1;
- }
- }
- inEnd:
- /* 受信処理終了 */
- if( rmcRecieveStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- loop1:
- if( rmcSendStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- return NOERR;
- }
-
- int waitSYN( int port ) /* ENQ送信 & SYN受信 */
- {
- int i, j, rcnt, ret;
-
- for( i = 0; i < (60 * 2 * 3); i++ ){ /* 3分間でタイムアウトに */
- /*(=(500msec * 2)*60*3秒) */
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return 2;
- }
- ret = rmcPutZaurus( port, enqDat, 8, repBuf, ZRCVMAX, &rcnt );
- if( ret!=0 && ret < 10 ){ /* 100ミリ秒待ち */
- // printf( "\nENQ送信時" );
- return 1;
- }
- if( ret == -1 || ret == 5 ){
- // printf( "\nENQ送信時 送信衝突" );
- // zdumpData( repBuf, rcnt );
- return 1;
- }
- if( !ret && rcnt ){
- if( !IR_repChk( repBuf, rcnt, SYN ) ){
- return 0;
- }
-
- if( !IR_repChk( repBuf, rcnt, ENQ ) ){
- // printf( "\nENQ送信時 ENQ衝突" );
- return 1;
- }
- if( !IR_repChk( repBuf, rcnt, CAN ) ){
- // printf( "\nENQ送信時 CAN受信" );
- return 1;
- }
- // printf( "\nSYN受信時 無効データ" );
- // zdumpData( repBuf, rcnt );
- }
- for( j = 0; j < 400 * 5; j++ ){ /* 400ミリ秒待ち */
- wait200mic(); /* (200マイクロ秒待ち*5*400) */
- }
- }
- // printf( "\nSYN待ちタイムアウト" );
- return 1;
- }
-
- // 同報送信
-
- int IR_onsideSend( void )
- {
- int ret, cnt, i, j, size, max;
-
- DM_showMsg( "◆ 光送信モード (右クリックで中断)◆", "(Wizの『光受信』をクリックして下さい)" );
- DM_dispCount( -1 ); // カウンタクリア
- max = (termSize / 512 )+1; // 全転送回数
-
- ret = rmcCommand ( irPort, 0x74 ); /* 最初のコマンド */
- if( ret!=0 ){
- goto loop1;
- }
- ret = rmcSendByte( irPort, 0x01 ); /* 次のコマンド */
- if( ret!=0 ){
- goto loop1;
- }
-
- WL_mkSendBuf(-1); // 転送前処理
-
- for( i = 0; i < BLOCKMAX; i++ ){
- if ( (size = WL_mkSendBuf(1)) < 1 ){
- break;
- }
- for( j = 0; j < 500 * 5; j++ ){
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return ERROR;
- }
- wait200mic(); /* 200マイクロ秒待ち */
- }
- // printf( "\nブロック[%d]を送っています。", i + 1 );
- DM_dispCount( max );
-
- ret = rmcPutZaurus( irPort, irBuf, size, repBuf, 16, &cnt );
- if ( ret != 0 ){
- if( rmcRecieveStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- }
- break;
- }
- }
- loop1:
- if( rmcSendStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- return NOERR;
- }
-
- // 同期送信
- int IR_syncSend( void )
- {
- int ret, rcnt, i, j, size, max;
-
- DM_showMsg( "◆ オプション送信モード (右クリックで中断)◆", "(Wizを受信状態にして下さい)" );
- DM_dispCount( -1 ); // カウンタクリア
- max = (termSize / 512 )+1; // 全転送回数を算出
-
- ret = rmcCommand ( irPort, 0x74 ); /* 最初のコマンド */
- if( ret!=0 ){
- goto loop1;
- }
- ret = rmcSendByte( irPort, 0x01 ); /* 次のコマンド */
- if( ret!=0 ){
- goto loop1;
- }
-
- WL_mkSendBuf(-1); // 転送前処理
-
- for( i = 0; i < BLOCKMAX; i++ ){
- if ( (size = WL_mkSendBuf(1)) < 1 ){
- break;
- }
- // printf( "\nブロック[%d]を送っています。", i + 1 );
- DM_dispCount( max );
-
- for( j = 0; j < RETRY; j++ ){
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return ERROR;
- }
- if( (ret=waitSYN( irPort ))!=0 ){ /* ENQ送信 & SYN受信 */
- if ( ret==2 ){
- // 右クリック中断
- return ERROR;
- }
- goto loop1;
- }
- do {
- // 右クリック中断
- if ( IR_checkBreak() != NOERR ){
- return ERROR;
- }
- /* データ送信 & 応答受信 */
- ret = rmcPutZaurus( irPort, irBuf, size, repBuf,
- ZRCVMAX, &rcnt );
- if( ret == -1 ){
- // printf( "\nデータ送信時、データ送出前に受信データがあった" );
- }
- } while( ret == -1 );
- if( ret == 13 || ret == 14 ){
- continue;
- }
- if( ret!=0 && ret != 3 && ret != 4 ){
- // printf( "\nデータ送信時" );
- goto loop1;
- }
- if( !rcnt ){
- // printf( "\n送信リトライ" );
- continue;
- }
- if( !IR_repChk( repBuf, rcnt, ACK ) ){
- break;
- }
- if( !IR_repChk( repBuf, rcnt, CAN ) ){
- goto loop1;
- }
-
- if( j < RETRY - 1 ){
- // printf( "\nACK待ち無効データ" );
- continue;
- }
-
- /* リトライオーバー CAN */
- do {
- ret = rmcPutZaurus( irPort, canDat, 8,
- repBuf, ZRCVMAX, &rcnt );
- } while( ret == -1 );
- // printf( "\nACK受信リトライ エラー" );
- goto loop1;
- }
- }
- loop1:
- if( rmcSendStop( irPort ) ){
- IR_dispErrWC( 1 ); // 『ワイヤレスコマンダがはずされました』表示
- return ERROR;
- }
- return NOERR;
- }
-